class PublicUtils {
    static formateSelector(selector) {
        if (selector.startsWith(".") || selector.startsWith("#")) {
            return selector.slice(1);
        }
        return selector;
    }

    static fillInPrompt(type = "positive", value) {
        if (value.trim() === '') {
            return;
        }
        let textarea = null;
        if (type === "positive") {
            textarea = document.querySelector(ElementSelector.sys_txt2img_prompt_positive_selector);
        } else {
            textarea = document.querySelector(ElementSelector.sys_txt2img_prompt_negative_selector);
        }
        if (textarea.value.trim() === '') {
            textarea.value = value;
        } else if (textarea.value.trim().endsWith(",")) {
            textarea.value += " " + value;
        } else {
            textarea.value += "," + value;
        }
        return textarea;
    }

    static updateInputElement(...inputElements) {
        if (typeof updateInput === "function") {
            inputElements.forEach(inputElement => {
                updateInput(inputElement);
            })
        } else {
            inputElements.forEach(inputElement => {
                inputElement.dispatchEvent(new Event('input'));
            })
        }
    }

    static isSelector(obj) {
        if (typeof obj === 'string') {
            return true;
        } else if (obj instanceof Element || obj instanceof HTMLElement) {
            return false;
        }
    }

    // 带动画切换高度
    static switchHeightWithAnimation(targets, {
        open = true,
        minHeight = 0,
        maxHeight = 0,
        padding = 0,
        paddingTop = 0,
        paddingBottom = 0,
        paddingLeft = 0,
        paddingRight = 0,
        borderWidth = 0,
        complete = (e) => {
        }
    }) {
        if (this.isSelector(targets)) {
            targets = document.querySelector(targets);
        }
        // padding 优先级更高
        if (padding !== 0) {
            paddingTop = paddingBottom = paddingLeft = paddingRight = padding;
        }
        // 如果没设置最大值，则默认使用 paddingTop+paddingBottom+scrollHeight
        if (maxHeight === 0) {
            maxHeight = targets.scrollHeight + paddingTop + paddingBottom;
        }
        anime({
            targets: targets,
            paddingTop: paddingTop,
            paddingBottom: paddingBottom,
            paddingLeft: paddingLeft,
            paddingRight: paddingRight,
            height: open ? maxHeight : minHeight,
            duration: 500,
            borderWidth: borderWidth,
            easing: 'easeOutQuad',
            complete: complete
        })
    }

    static async readFile(filepath) {
        // 通过 new Date().getTime() 获取当前时间的时间戳，并将其添加到 URL 的查询参数中，以确保每次请求都是唯一的
        // https://www.jianshu.com/p/e18ced22cfaa
        const response = await fetch(`file=${filepath}?${new Date().getTime()}`);
        return await response.text();
    }

    static async parseFileAsJson(filepath) {
        const tagsJson = await this.readFile(filepath);
        if (tagsJson === '') {
            return {};
        }
        return JSON.parse(tagsJson);
    }

    // 获取元素内容高度
    static getContentHeight(element) {
        if (this.isSelector(element)) {
            element = document.querySelector(element);
        }
        // 首先判断是否有溢出，如果有溢出，则直接为 scrollHeight
        // 否则设置高度为 0 px,再次获取 scrollHeight
        if (element.scrollHeight > element.clientHeight) {
            // 内容超出，返回 scrollHeight
            return element.scrollHeight;
        } else {
            element.style.height = 0 + 'px';
            return element.scrollHeight;
        }
    }

    // 当添加子元素时自适应高度(适用于js给元素设置了固定高的情况下）
    static autoAdjustHeightOnElementContentChange(element, {
        childChange = true,
        windowChange = true,
        auto = false
    }) {
        console.log(element)
        if (this.isSelector(element)) {
            element = document.querySelector(element);
        }
        console.log(element)
        if (!element) {
            throw Error("第一个参数不是正确的元素选择器或DOM元素");
        }
        let observer = null;
        const resizeListener = () => {
            element.style.height = PublicUtils.getContentHeight(element) + 'px';
        }
        const start = () => {
            if (childChange) {
                // 创建一个 MutationObserver 实例
                observer = new MutationObserver(function (mutationsList, observer) {
                    // 遍历所有变化
                    for (const mutation of mutationsList) {
                        if (mutation.type === 'childList') {
                            element.style.height = PublicUtils.getContentHeight(element) + 'px';
                        }
                    }
                });

                // 配置 MutationObserver
                const config = {childList: true, subtree: true};

                // 开始观察目标元素及其子元素的变化
                observer.observe(element, config);

                // 停止观察
                // observer.disconnect();
            }

            if (windowChange) {
                window.addEventListener("resize", resizeListener)
            }
        }

        const stop = () => {
            try {
                if (observer) {
                    observer.disconnect();
                }
                if (windowChange) {
                    window.removeEventListener("resize", resizeListener);
                }
            } catch (e) {
                console.log("取消事件出错")
            }
        }
        if (auto) {
            start();
        }
        return {
            targetElement: element,
            stop: stop,
            start: start
        }
    }

    // 禁止页面滚动
    static disableScroll() {
        document.body.style.overflow = 'hidden';
    }

    // 启用页面滚动
    static enableScroll() {
        document.body.style.overflow = 'auto';
    }

    // 弹出框
    static customDialog(message) {
        // 创建对话框
        const dialog = document.createElement("dialog");
        document.body.appendChild(dialog);
        dialog.style.position = "fixed";
        dialog.show();
        dialog.textContent = message;

        setTimeout(() => {
            dialog.close();
            dialog.remove();
        }, 1500)
    }
}